﻿using System;
using System.Net;
using System.Linq;
using System.Collections;
using System.Collections.Generic;
using Model.StrategyEntities;

namespace BLL
{
    public sealed partial class AnalysisEngine
    {
        /// <summary>
        /// Calculates Simple Moving Average (SMA) indicator
        /// </summary>
        /// <param name="input">Input signal</param>
        /// <param name="periods">Number of periods</param>
        /// <param name="returnImmatureValues">Determines whether immature values should be taken into account</param>
        /// <returns>Object containing operation results</returns>
        public static SMAResult SMA(IEnumerable<decimal> input, int periods, bool returnImmatureValues)
        {
            var returnValues = new List<decimal>();

            if (returnImmatureValues)
            {
                for (int i = 0; i < input.Count(); i++)
                {
                    var resultValue = input
                        .Skip(i + 1 > periods ? i + 1 - periods : 0)
                        .Take(i >= periods ? periods : i + 1)
                        .Average();

                    returnValues.Add(resultValue);
                }
            }
            else
            {
                var copyInputValues = input.ToList();

                for (int i = 0; i < input.Count() - periods + 1; i++)
                {
                    var resultValue = copyInputValues.GetRange(i, periods).Average();

                    returnValues.Add(resultValue);
                }
            }

            var result = new SMAResult()
            {
                Values = returnValues,
                StartIndexOffset = periods - 1
            };

            return result;
        }

        /// <summary>
        /// Calculates Simple Moving Average (SMA) indicator
        /// </summary>
        /// <param name="input">Input signal</param>
        /// <param name="periods">Number of periods</param>
        /// <returns>Object containing operation results</returns>
        public static SMAResult SMA(IEnumerable<decimal> input, int periods)
        {
            return SMA(input, periods, false);
        }

        /// <summary>
        /// 先将传入的序列反转，再求均值
        /// 返回的均值为反转后的序列
        /// </summary>
        /// <param name="input">Input signal</param>
        /// <param name="periods">Number of periods</param>
        /// <returns>Object containing operation results</returns>
        public static SMAResult SMA_Reverse(IEnumerable<decimal> input, int periods)
        {
            //此处IEnumerable为值类型参数，不用考虑外层被修改
            var input_new = input.Reverse();
            //int precision = 2;
            //List<decimal> input_new_2 = new List<decimal>();
            //foreach (decimal item in input_new)
            //{
            //    input_new_2.Add(Convert.ToDecimal(item.ToString("F2")));
            //}
            //return SMA(input_new_2, periods, false);
            return SMA(input_new, periods, false);
        }

    }
}

